package com.jiangyg.mall.ware.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jiangyg.mall.core.exception.BusinessException;
import com.jiangyg.mall.core.support.restful.Pagination;
import com.jiangyg.mall.core.utils.bean.BeanUtils;
import com.jiangyg.mall.db.mybatis.BaseServiceImpl;
import com.jiangyg.mall.db.mybatis.metadata.Pager;
import com.jiangyg.mall.product.service.SkuService;
import com.jiangyg.mall.product.vo.SkuInfoVO;
import com.jiangyg.mall.ware.constant.ColumnConstant;
import com.jiangyg.mall.ware.dao.PurchaseDao;
import com.jiangyg.mall.ware.dao.PurchaseDetailDao;
import com.jiangyg.mall.ware.dao.WareInfoDao;
import com.jiangyg.mall.ware.dto.PurchaseDetailCombineDTO;
import com.jiangyg.mall.ware.dto.PurchaseDetailDTO;
import com.jiangyg.mall.ware.entity.Purchase;
import com.jiangyg.mall.ware.entity.PurchaseDetail;
import com.jiangyg.mall.ware.entity.WareInfo;
import com.jiangyg.mall.ware.enums.PurchaseStatus;
import com.jiangyg.mall.ware.vo.PurchaseDetailVO;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class PurchaseDetailServiceImpl extends BaseServiceImpl<PurchaseDetailDao, PurchaseDetail> implements PurchaseDetailService {

    private final PurchaseDao purchaseDao;

    private final WareInfoDao wareInfoDao;

//    @Reference
    @Autowired
    private SkuService skuService;

    @Autowired
    public PurchaseDetailServiceImpl(WareInfoDao wareInfoDao,
                                     PurchaseDao purchaseDao,
                                     PurchaseDetailDao purchaseDetailDao) {
        super(purchaseDetailDao);
        this.wareInfoDao = wareInfoDao;
        this.purchaseDao = purchaseDao;
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public Pagination<PurchaseDetailVO> selectPagination(Pagination<PurchaseDetailVO> pagination) throws Exception {
        Pager<PurchaseDetail> pager = new Pager<>();
        pager.setSize(pagination.getSize());
        pager.setCurrent(pagination.getCurrent());
        {
            // 高级查询条件组装
            final QueryWrapper<PurchaseDetail> wrapper = this.buildQueryWrapper(pagination, PurchaseDetail.class);
            // 普通条件拼接
            final String condition = MapUtils.getString(pagination.toSearchMap(), "condition");
            if (StringUtils.isNotBlank(condition)) {
                wrapper.eq(ColumnConstant.SKU_ID, condition).or().eq(ColumnConstant.PURCHASE_ID, condition);
            }
            // 执行查询
            pager = baseMapper.selectPage(pager, wrapper);
        }
        pagination.setRecords(BeanUtils.transformList(pager.getRecords(), PurchaseDetailVO.class));
        pagination.setTotal(pager.getTotal());
        {
            // 如果没查询到数据则直接返回
            if (pager.getTotal() == 0) {
                return pagination;
            }
            // 仓库名称反写
            final List<Long> wareIdList = pager.getRecords().stream()
                    .map(PurchaseDetail::getWareId).distinct().collect(Collectors.toList());
            final QueryWrapper<WareInfo> wrapper = new QueryWrapper<>();
            wrapper.in(ColumnConstant.ID, wareIdList);
            final List<WareInfo> wareInfoList = this.wareInfoDao.selectList(wrapper);
            final Map<String, String> wareMap = wareInfoList.stream()
                    .collect(Collectors.toMap(k -> k.getId().toString(), WareInfo::getName));
            pagination.getRecords().forEach(data -> data.setWareName(MapUtils.getString(wareMap, data.getWareId())));
        }
        return pagination;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveOrUpdate(PurchaseDetailDTO dto) throws Exception {
        // 判断SKUID是否存在
        final SkuInfoVO skuInfo = skuService.selectById(dto.getSkuId());
        if (skuInfo == null) {
            throw BusinessException.instance("mall.ware.skuinfo.notexist");
        }
        return this.executeSaveOrUpdate(dto) > 0;
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public PurchaseDetailVO selectById(Long purchaseDetailId) throws Exception {
        return this.executeSelectById(purchaseDetailId, PurchaseDetailVO.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean delete(List<Long> purchaseDetailIds) {
        return this.baseMapper.deleteBatchIds(purchaseDetailIds) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean combine(PurchaseDetailCombineDTO dto) {
        // 采购单信息（没有指定采购单，则新建一个）
        Purchase purchase;
        if (dto.getPurchaseId() == null) {
            purchase = new Purchase();
            purchase.setPriority(0);
            purchase.setStatus(PurchaseStatus.NEW.code);
            purchase.setWareId(dto.getWareId());
            purchase.setCreateTime(new Date());
            this.purchaseDao.insert(purchase);
        } else {
            purchase = this.purchaseDao.selectById(dto.getPurchaseId());
            if (PurchaseStatus.decide(purchase.getStatus()) != PurchaseStatus.NEW) {
                throw BusinessException.instance("mall.ware.purchasedetail.combine.purchasenotnew.error");
            }
        }
        // 采购需求信息
        final QueryWrapper<PurchaseDetail> wrapper = new QueryWrapper<>();
        wrapper.in(ColumnConstant.ID, dto.getPurchasedetailIds());
        final List<PurchaseDetail> detailList = this.baseMapper.selectList(wrapper);
        // 校验：仓库必须同一个且状态为新建
        for (PurchaseDetail purchaseDetail : detailList) {
            if (PurchaseStatus.decide(purchaseDetail.getStatus()) != PurchaseStatus.NEW) {
                throw BusinessException.instance("mall.ware.purchasedetail.combine.detailnotnew.error");
            }
            if (!purchaseDetail.getWareId().equals(purchase.getWareId())) {
                throw BusinessException.instance("mall.ware.purchasedetail.combine.notsameware.error");
            }
        }
        // 校验通过，直接更新
        final PurchaseDetail updateDetail = new PurchaseDetail();
        updateDetail.setPurchaseId(purchase.getId());
        final int count = this.baseMapper.update(updateDetail, wrapper);
        // 计算总金额
        this.purchaseDao.computeAmountPurchase(purchase.getId());
        return count > 0;
    }

}
